<template>

  <div class="framework">
    <!-- 头部 -->
    <div class="header">
        <div class="logo">
            <span class="iconfont icon-pan"></span>
            <div class="name">Pithy云盘</div>
        </div>
        <div class="right-panel">
            <!-- 文件上传窗口 -->
            <!-- v-model:visible: 用于控制窗口开关 -->
            <el-popover 
              :width="800" 
              trigger="click" 
              v-model:visible="showUploader" 
              :offset="20" 
              transition="none"
              :hide-after="0"
              :popper-style="{ padding: '0px' }"
              >
                <template #reference>
                    <span class="iconfont icon-transfer"></span>
                </template>
                <template #default> 
                    <Uploader ref="uploaderRef" @uploadCallback="uploadCallbackHandler"></Uploader> 
                </template>
              </el-popover>

              <el-dropdown>
                <div class="user-info">
                    <!-- 头像 -->
                    <div class="avatar">
                        <!-- 自定义组件，main.js -- 17行注册   属性为向子组件传递参数 -->
                        <Avatar 
                          :userId="userInfo.userId" 
                          :avatar="userInfo.avatar"
                          :timestamp="timestamp"
                        ></Avatar>
                    </div>
                    <!-- 用户名 -->
                    <div class="nick-name"> {{ userInfo.nickName }} </div>
                </div>
                <template #dropdown>
                    <el-dropdown-menu>
                        <el-dropdown-item @click="updateAvatar">修改头像</el-dropdown-item>
                        <el-dropdown-item @click="updatePassword">修改密码</el-dropdown-item>
                        <el-dropdown-item @click="logout">退出</el-dropdown-item>
                    </el-dropdown-menu>
                </template>
              </el-dropdown>
        </div>
    </div>

    <!-- 列表框（循环 menus数组） -->
    <div class="body">
        <div class="left-sider">
            <div class="menu-list">
                <div @click="jump(item);" v-for="(item, index) in menus" :key="index" :class="['menu-item', item.menuCode == currentMenu.menuCode ? 'active' : '']">
                    <div :class="['iconfont', 'icon-' + item.icon]"></div>
                    <div class="text"> {{ item.name }} </div>
                </div>
            </div>
            <div class="menu-sub-list">
                <div @click="jump(sub)"  v-for="(sub, index) in currentMenu.children" :key="index"  :class="['menu-item-sub', sub.path == currentPath ? 'active' : '']" >
                    <span :class="['iconfont', 'icon-' + sub.icon]"   v-if="sub.icon"></span>
                    <span class="text"> {{ sub.name }} </span>
                </div>

                <div class="tips"  v-if="currentMenu && currentMenu.tips"> {{ currentMenu.tips }} </div>

                <!-- 空间信息 -->
                <div class="space-info">
                    <div>空间使用</div>
                    <div class="percent">
                        <!-- 占比条 -->
                        <el-progress :percentage="Math.floor( (useSpaceInfo.useSpace / useSpaceInfo.totalSpace) * 10000 ) / 100 " color="#409eff"></el-progress>
                    </div>
                    <div class="space-use">
                        <!-- 空间情况 -->
                        <div class="use">
                            {{ proxy.Utils.size2Str(useSpaceInfo.useSpace) }} / {{ proxy.Utils.size2Str(useSpaceInfo.totalSpace) }}
                        </div>
                        <!-- 刷新按钮 -->
                        <div class="iconfont icon-refresh" @click="getUseSpace"></div>
                    </div>
                </div>
            </div>
        </div>
        <div class="body-content">
            <router-view v-slot="{ Component }">
                <!-- 通过路由（/router/index.js的28行、37行...），引进对应的文件（如：Main.vue、Share.vue等） -->
                <component ref="routerViewRef" @reload="getUseSpace" :is="Component" @addFile="addFile"></component>
            </router-view>
        </div>
    </div>

    <!-- 自定义组件 -- 修改头像
           @updateAvatar通过子组件UpdateAvatar.vue触发 -- submitForm方法中
           ref="updateAvatarRef" 可用于调用UpdateAvatar.vue子组件对外暴露的方法 -->
    <UpdateAvatar ref="updateAvatarRef" @updateAvatar="reloadAvatar"></UpdateAvatar>

    <!-- 自定义组件 -- 修改密码 -->
    <UpdatePassword ref="updatePasswordRef"></UpdatePassword>
  </div>
  
</template>

<script setup>
import { ref, reactive, getCurrentInstance, nextTick, onMounted, watch } from "vue";
import { useRoute, useRouter } from "vue-router"
import Uploader from "@/views/main/Uploader.vue";     //引入自定义组件
import UpdateAvatar from "./UpdateAvatar.vue";        //引入自定义组件
import UpdatePassword from "./UpdatePassword.vue";    //引入自定义组件
const { proxy } = getCurrentInstance();
const router = useRouter();
const route = useRoute();

const userInfo = ref( proxy.VueCookies.get("userInfo") );  //从cookie中获取登陆用户信息
const timestamp = ref(0);      //用户刷新头像的时间戳

const menus = [
    {
        icon: "cloude",
        name: "首页",
        menuCode: "main",
        path: "/main/all",
        allShow: true,
        children: [
            {
                icon: "all",
                name: "全部",
                category: "all",
                path: "/main/all",
            },
            {
                icon: "video",
                name: "视频",
                category: "video",
                path: "/main/video",
            },
            {
                icon: "music",
                name: "音频",
                category: "music",
                path: "/main/music",
            },
            {
                icon: "image",
                name: "图片",
                category: "image",
                path: "/main/image",
            },
            {
                icon: "doc",
                name: "文档",
                category: "doc",
                path: "/main/doc",
            },
            {
                icon: "more",
                name: "其他",
                category: "others",
                path: "/main/others",
            },
        ],
    },
    {
        icon: "share",
        name: "分享",
        menuCode: "share",
        path: "/myshare",
        allShow: true,
        children: [
            {
                name: "分享记录",
                path: "/myshare",
            },
        ],
    },
    {
        icon: "del",
        name: "回收站",
        menuCode: "recycle",
        path: "/recycle",
        tips: "回收站为您保存10天内删除的文件",
        allShow: true,
        children: [
            {
                name: "删除的文件",
                path: "/recycle",
            },
        ],
    },
    {
        icon: "settings",
        name: "设置",
        menuCode: "settings",
        path: "/settings/fileList",
        allShow: false,
        children: [
            {
                name: "用户文件",
                path: "/settings/fileList",
            },
            {
                name: "用户管理",
                path: "/settings/userList",
            },
            {
                name: "系统设置",
                path: "/settings/sysSetting",
            },
        ],
    },
];

const currentMenu = ref({});
const currentPath = ref();

const jump = (data) => {
    if (!data.path || data.menuCode == currentMenu.value.menuCode) {
        return;
    }
    router.push(data.path);
};

const setMenu = (menuCode, path) => {
    const menu = menus.find(item => {
        return item.menuCode === menuCode;
    })
    currentMenu.value = menu;
    currentPath.value = path;
};
watch(
    () => route,
    (newVal, oldVal) => {
        if (newVal.meta.menuCode) {
            setMenu(newVal.meta.menuCode, newVal.path);
        }
    },
    { immediate: true, deep: true }
);

const showUploader = ref(false);    //用于控制上传区域窗口的开关
const uploaderRef = ref();          //用于调用子组件的方法

//文件上传 -- 由组件main/Main.vue的addFile方法触发
const addFile = (data) => {
    const {file, filePid} = data;
    showUploader.value = true;                   //打开上传区域窗口
    uploaderRef.value.addFile(file, filePid);    //调用Uploader.vue组件暴露的方法
};


const routerViewRef = ref();   //93行定义，用于调用子组件暴露的方法
//上传文件完成回调，通过子组件Uploader.vue触发 -- uploadFile方法末尾
const uploadCallbackHandler = () => {
    nextTick(() => {
        routerViewRef.value.reload();    //调用方法
        getUseSpace();                   //更新用户空间
    })
};


const updateAvatarRef = ref();   //用于调用子组件的方法
//修改头像按钮
const updateAvatar = () => {
    updateAvatarRef.value.show(userInfo.value);   //调用UpdateAvatar.vue 组件暴露的方法
};

//更新头像成功回调，通过子组件UpdateAvatar.vue触发 -- submitForm方法中
const reloadAvatar = () => {
    userInfo.value = proxy.VueCookies.get("userInfo"); //获取更新后的登陆用户信息
    console.log("Framework.vue -- 235,更新头像完成，刷新头像");
    timestamp.value = new Date().getTime();            //更新时间戳
};


const updatePasswordRef = ref();      //用于调用子组件的方法
//修改密码按钮
const updatePassword = () => {
    updatePasswordRef.value.show();   //调用UpdatePassword.vue暴露的方法
};


//退出登陆按钮
const logout = async () => {
    proxy.Confirm("是否确定退出", async () => {   //proxy.Confirm  ==》 utils/Confirm.js
        let result = await proxy.Request({       //发送退出登陆请求
            url: "/logout",
        });
        if (!result) {
            return;
        }
        proxy.VueCookies.remove("userInfo");     //删除cookie中的登陆用户
        router.push("/login");                   //跳转
    })
};


//获得用户的使用空间
const useSpaceInfo = ref({useSpace: 0, totalSpace: 1});
const getUseSpace = async () => {
    let result = await proxy.Request({
        url: "getUseSpace",
        showLoading: false,
    });
    if (!result) {
        return;
    }
    useSpaceInfo.value = result.data.spaceDto;
};

getUseSpace();    //加载后即刻调用

</script>

<style lang="scss" scoped>
//     在vue中:Ap.vue相当于根容器,不设置 scoped。所以一般在App.vue中引用公共样式。
// 而在其它.vue页面中用 scoped,代表当前样式只作用于当前vue页面。不作用于其它.vue页面。
//头部样式
.header {
    box-shadow: 0 3px 10px 0 rgb(0 0 0 / 6%);
    height: 56px;
    padding-left: 24px;
    padding-right: 24px;
    position: relative;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: space-between;

    .logo {
        display: flex;
        align-items: center;
        .icon-pan {
            font-size: 40px;
            color: #1296db;
        }
        .name {
            font-weight: bold;
            margin-left: 5px;
            font-size: 25px;
            color: #05a1f5;
        }
    }

    .right-panel {
        display: flex;
        align-items: center;
        .icon-transfer {
            cursor: pointer;
        }
        .user-info {
            margin-right: 10px;
            display: flex;
            align-items: center;
            cursor: pointer;
            .avatar {
                margin: 0px 5px 0px 15px;
            }
            .nick-name {
                color: #05a1f5;
            }
        }
    }
}

//主体部样式
.body {
    display: flex;
    .left-sider {
        border-right: 1px solid #f1f2f4;
        display: flex;
        .menu-list {
            height: calc(100vh - 56px);
            width: 80px;
            box-shadow: 0 3px 10px 0 rgb(0 0 0 / 6%);
            border-right: 1px solid #f1f2f4;
            .menu-item {
                text-align: center;
                font-size: 14px;
                font-weight: bold;
                padding: 20px 0px;
                cursor: pointer;
                &:hover {
                    background: #f3f3f3;
                }
                .iconfont {
                    font-weight: normal;
                    font-size: 28px;
                }
            }
            .active {
                .iconfont {
                    color: #06a7ff;
                }
                .text {
                    color: #06a7ff;
                }
            }
        }
        .menu-sub-list {
            width: 200px;
            padding: 20px 10px 0px;
            position: relative;
            .menu-item-sub {
                text-align: center;
                line-height: 40px;
                border-radius: 5px;
                cursor: pointer;
                &:hover {
                    background: #f3f3f3;
                }
                .iconfont {
                    font-size: 14px;
                    margin-right: 20px;
                }
                .text {
                    font-size: 13px;
                }
            }
            .active {
                background: #eef9fe;
                .iconfont {
                    color: #05a1f5;
                }
                .text {
                    color: #05a1f5;
                }
            }

            .tips {
                margin-top: 10px;
                color: #888888;
                font-size: 13px;
            }

            .space-info {
                position: absolute;
                bottom: 10px;
                width: 100%;
                padding: 0px 5px;
                .percent {
                    padding-right: 10px;
                }
                .space-use {
                    margin-top: 5px;
                    color: #7e7e7e;
                    display: flex;
                    justify-content: space-around;
                    .use {
                        flex: 1;
                    }
                    .iconfont {
                        cursor: pointer;
                        margin-right: 20px;
                        color: #05a1f5;
                    }
                }
            }
        }
    }
    .body-content {
        flex: 1;
        width: 0;
        padding-left: 20px;
    }
}
</style>
